Load Packages

First I need to load up the packages I’ll need

library(sf)
Linking to GEOS 3.4.2, GDAL 2.1.2, proj.4 4.9.1
library(ggplot2) #development version!
## devtools::install_github("tidyverse/ggplot2")
library(tidyverse)
Loading tidyverse: tibble
Loading tidyverse: tidyr
Loading tidyverse: readr
Loading tidyverse: purrr
Loading tidyverse: dplyr
Conflicts with tidy packages -------------------------------------------------------
filter(): dplyr, stats
lag():    dplyr, stats
library(readr)
## Not sure about this bit
#library("tidyverse",lib.loc="/Library/Frameworks/R.framework/Versions/3.4/Resources/library")
library(cowplot)

Attaching package: ‘cowplot’

The following object is masked from ‘package:ggplot2’:

    ggsave
library(sp)

Import Data

Now I import my data. I filter for the Arran postcodes, (since Arran all begins ‘KA27’).

## Finding the Arran coordinates
library(dplyr)
allcoordinates <- read.csv("alldata/ukpostcodes.csv")
arrancoordinates <- filter(allcoordinates,substr(postcode,1,4)=="KA27")

Plot Coordinates

Now I plot these coordinates.

## Plotting the Arran coordinates
ggplot(data = arrancoordinates) +
  geom_point(mapping = aes(x = longitude, y = latitude)) +
  ggtitle("Arran Postcodes") +
  labs(title = "Arran Postcodes", x = "Longitude", y = "Latitude") +
  theme(plot.title = element_text(hjust = 0.5)) +
  theme_grey() +
  coord_map()

Now I create some plots. #Arran Borders

pcs <- read_sf("alldata/Scotland_pcs_2011")
#Print Post codes lists
arransubsect <- filter(pcs,substr(label,1,4)=="KA27")
arransubsect %>%
  ggplot() +
  geom_sf() +
  theme(axis.text.x=element_text(angle=45, hjust = 1)) +
  theme_grey()

After a little editing I can overlay the two.

simple.sf <- st_as_sf(arrancoordinates, coords=c('longitude','latitude'))
st_crs(simple.sf) <- 4326
simple.sf %>% ggplot() + geom_sf() +
theme_grey() 

arransubsect %>%
  ggplot() +
  geom_sf() +
  theme(axis.text.x=element_text(angle=45, hjust = 1)) +
  theme_grey() +
  geom_sf(data=simple.sf)

Shape files

Now I can load the SIMD data, starting with the shape files.

#Import SIMD data from http://www.gov.scot/Topics/Statistics/SIMD
#The "new data zone boundaries with SIMD16 ranks (zipped shapefile)"
#'2011 Data Zone boundaries'
DZBoundaries2016 <- read_sf("./alldata/SG_SIMD_2016")
#https://data.gov.uk/dataset/scottish-index-of-multiple-deprivation-simd-2012
#https://data.gov.uk/dataset/scottish-index-of-multiple-deprivation-simd-2012/resource/d6fa8924-83da-4e80-a560-4ef0477f230b
DZBoundaries2012 <- read_sf("./alldata/SG_SIMD_2012")
DZBoundaries2009 <- read_sf("./alldata/SG_SIMD_2009")
DZBoundaries2006 <- read_sf("./alldata/SG_SIMD_2006")
DZBoundaries2004 <- read_sf("./alldata/SG_SIMD_2004")

Load SIMD data

Then (having already downloaded it), I can load the SIMD data.

#Look at data from 2016
SIMD2016 <-read.csv("./alldata/00505244.csv")
SIMD20162 <-read_sf("./alldata/SG_SIMD_2016")
#Look at data from 2012
SIMD2012 <- readxl::read_excel("./alldata/SIMD2012/00410770.xls")
SIMD20122 <- readxl::read_excel("./alldata/SIMD2012/00416552.xls")
#Look at data from 2009
SIMD2009 <- readxl::read_excel("./alldata/SIMD2009/0096578.xls")
SIMD20092 <- readxl::read_excel("./alldata/SIMD2009/0097806.xls")
#Look at data from 2006
# 2009 data - SIMD2006 <- readxl::read_excel("./alldata/SIMD2006/0096578.xls")
SIMD20062 <- readxl::read_excel("./alldata/SIMD2006/0097880.xls")
#Look at data from 2004
SIMD2004 <- readxl::read_excel("./alldata/SIMD2004/0027003.xls")

Select Arran SIMD data

I have to choose the right columns manually in order to select the Arran data.

#Selecting ArranDZ2016
Arrandz <- c(4672,4666,4669,4671,4667,4668,4670)
#Health domain rank
#2016
arran2016 <- SIMD20162[Arrandz,]
#Find postcode look-up, KA27 postcodes. Find unique DZ. Find row positions.
#Selecting ArranDZ2012
Arrandz2012 <- c(4409,4372,4353,4352,4351,4350,4349)
#2012
arran2012 <- DZBoundaries2012[Arrandz2012,]
#2009
arran2009 <- DZBoundaries2009[Arrandz2012,]
#2006
arran2006 <- DZBoundaries2006[Arrandz2012,]
#2004
arran2004 <- DZBoundaries2004[Arrandz2012,]

The reason I’ve downloaded all the datazones shapefiles individually (three steps up), is because they change between 2016 and 2012.

arran20162 <- arran2016 %>%
  select(DataZone, geometry, Percentile)  %>%
  mutate(year="2016")
arran20122 <- arran2012 %>%
  select(DataZone, geometry, Percentile) %>%
  mutate(year="2012")
arran1612 <- rbind(arran20162,arran20122)

See the small difference.

arran1612 %>%
  ggplot() +
  geom_sf(aes(fill = DataZone)) +
  facet_wrap('year') +
  theme_grey() +
  theme(legend.position="none") +
  theme(axis.text.x=element_text(angle=45, hjust = 1))

Now I want to plot all the data, first I combine it all into one table. First I subselect the data I want from the appropriate columns.

arran20092 <- arran2009 %>%
  select(DataZone, geometry, Percentile) %>%
  mutate(year="2009")
arran20062 <- arran2006 %>%
  select(DataZone, geometry, Percentile) %>%
  mutate(year="2006")
arran20042 <- arran2004 %>%
  select(DataZone, geometry, Percentile) %>%
  mutate(year="2004")
arransimd <- rbind(arran20162,arran20122,arran20092,arran20062,arran20042)

Arran Percentile Plots

Now I plot the percentiles.

arransimd %>%
  ggplot() +
  geom_sf(aes(fill = Percentile)) +
  facet_wrap('year') +
  theme_grey() +
  theme(axis.text.x=element_blank(),
        axis.ticks.x=element_blank(), axis.text.y=element_blank(),
        axis.ticks.y=element_blank())

There we are. Not the SIMD health percentiles of Arran zones throughout SIMD history. And I’ve learned a little bit about graphics in R.

If I wanted to I could show the zones individually..

First I find the unique zones. (There are 14. 7 Zones 2016, 7 Zones pre-2016)

datazones <- unique(arransimd$DataZone)

I’ll have to find out a simpler way to do this but..

Pre-2016 Individual Zones

S01004409 <- filter(arransimd, DataZone=="S01004409")
S01004372 <- filter(arransimd, DataZone=="S01004372")
S01004353 <- filter(arransimd, DataZone=="S01004353")
S01004352 <- filter(arransimd, DataZone=="S01004352")
S01004351 <- filter(arransimd, DataZone=="S01004351")
S01004350 <- filter(arransimd, DataZone=="S01004350")
S01004349 <- filter(arransimd, DataZone=="S01004349")
pre2016list <- list(S01004409, S01004372, S01004353, S01004352, S01004351, S01004350, S01004349)
function1 <- function(argument) 
{
  argument %>%
  ggplot() +
  geom_sf(aes(fill = Percentile)) +
  facet_wrap('year') +
  theme_grey() +
  theme(axis.text.x=element_blank(),
        axis.ticks.x=element_blank())
}
function2 <- function(argument) 
{
  arransubsect %>%
  ggplot() +
  geom_sf() +
  theme_grey() +
  theme(axis.text.x=element_text(angle=45, hjust = 1)) +
  geom_sf(data= argument, aes(fill = DataZone))
}
function3 <- function(argument) 
{
  argument %>%
  ggplot() +
  geom_sf(data = arransubsect) +
  geom_sf(aes(fill = Percentile)) +
  facet_wrap('year') +
  theme_grey() +
  theme(axis.text.x=element_blank(),
        axis.ticks.x=element_blank())
}
function4 <- function(argument) 
{
  plot_grid((function1(argument)), (function2(argument)), labels = c("A", "B"))
}
lapply(pre2016list, function4)
[[1]]

[[2]]

[[3]]

[[4]]

[[5]]

[[6]]

[[7]]

2016

Now I apply the same functions to the post-2016 Zones

arransubsect <- filter(pcs,substr(label,1,4)=="KA27")
S01011177 <- filter(arransimd, DataZone=="S01011177")
S01011171 <- filter(arransimd, DataZone=="S01011171")
S01011174 <- filter(arransimd, DataZone=="S01011174")
S01011176 <- filter(arransimd, DataZone=="S01011176")
S01011172 <- filter(arransimd, DataZone=="S01011172")
S01011173 <- filter(arransimd, DataZone=="S01011173")
S01011175 <- filter(arransimd, DataZone=="S01011175")
post2016list <- list(S01011177, S01011171, S01011174, S01011176, S01011172, S01011173, S01011175)
lapply(pre2016list, function4)
[[1]]

[[2]]

[[3]]

[[4]]

[[5]]

[[6]]

[[7]]

Plot the percentiles as bar charts.

Pre-2016

arransimd2 <- dplyr::filter(arransimd, year < 2016)
arransimd2 %>%
ggplot(aes(x=year, y=Percentile)) +
  geom_bar(stat="identity") +
  facet_wrap('DataZone') +
  theme_grey() +
  labs(title = "Arran SIMD Datazones", x = "Year", y = "Percentile") +
  theme(plot.title = element_text(hjust = 0.5))

Post-2016

arransimd3 <- dplyr::filter(arransimd, year >= 2016)
arransimd3 %>%
ggplot(aes(x=year, y=Percentile)) +
  geom_bar(stat="identity") +
  facet_wrap('DataZone') +
  theme_grey() +
  labs(title = "Arran SIMD Datazones", x = "Year", y = "Percentile") +
  theme(plot.title = element_text(hjust = 0.5))

Now I want to overlay the postcodes for a particular shapefile, in this case by Datazone. To do this I’ve converted both the Arran coordinates and Arran (2016) shapefiles into Spatial Points/Polygons, converted them into a common CRS, and then compared them by using over().

exampleshapes <- sf:::as_Spatial(arran2016$geom)
examplepoints <- sf:::as_Spatial(simple.sf$geom)
examplepoints <- spTransform(examplepoints, CRS("+proj=longlat +datum=WGS84"))
exampleshapes <- spTransform(exampleshapes, CRS("+proj=longlat +datum=WGS84"))
namingdzpostcode <- over(exampleshapes, examplepoints, returnList = TRUE)

I can then take a member reference from the orginal postcode list, which gives me a selection of the rows in that DZ. For simplicity I’ve written this as a new function.

Unfortunately, I haven’t worked out how to coordinate the new ID with the original DZ names yet, so I have to select by using the appropriate ID for each DZ. #Function selecting simple.sf by DZ ID.

function6 <- function(argument) 
{
  simple.sf[namingdzpostcode[[argument]],]
}

I can then use the above, and plot over the appropriate DZ shapefile. e.g

Projecting the coordinate selections

function1(S01004372) +
  geom_sf(data=function6(2))

function2(S01004372) +
  geom_sf(data=function6(2))

function3(S01004372) +
  geom_sf(data=function6(2))

If I edit function 4 a little so that the geom_sf layer is a second argument then I can also use function 4.

function4.5 <- function(argument, argument2) 
{
  a <- function1(argument)
  b <- function2(argument) +
  geom_sf(data=function6(argument2))
  plot_grid(a, b, labels = c("A", "B"))
}
function4.5(S01004372,2)

I’ve also made another function to plot the DZ on it’s own with coordinates.

function5 <- function(argument, argument2) 
{
  argument %>%
  ggplot() +
  geom_sf() +
  theme_grey() +
  geom_sf(data=function6(argument2)) +
  theme(axis.text.x=element_blank(),
        axis.ticks.x=element_blank())
}
function5(S01004372,2)

LS0tCnRpdGxlOiAiQXJyYW4iCm91dHB1dDoKICBodG1sX2RvY3VtZW50OiBkZWZhdWx0CiAgaHRtbF9ub3RlYm9vazogZGVmYXVsdAotLS0KCiNMb2FkIFBhY2thZ2VzCkZpcnN0IEkgbmVlZCB0byBsb2FkIHVwIHRoZSBwYWNrYWdlcyBJJ2xsIG5lZWQKYGBge3J9CmxpYnJhcnkoc2YpCmxpYnJhcnkoZ2dwbG90MikgI2RldmVsb3BtZW50IHZlcnNpb24hCiMjIGRldnRvb2xzOjppbnN0YWxsX2dpdGh1YigidGlkeXZlcnNlL2dncGxvdDIiKQpsaWJyYXJ5KHRpZHl2ZXJzZSkKbGlicmFyeShyZWFkcikKIyMgTm90IHN1cmUgYWJvdXQgdGhpcyBiaXQKI2xpYnJhcnkoInRpZHl2ZXJzZSIsbGliLmxvYz0iL0xpYnJhcnkvRnJhbWV3b3Jrcy9SLmZyYW1ld29yay9WZXJzaW9ucy8zLjQvUmVzb3VyY2VzL2xpYnJhcnkiKQpsaWJyYXJ5KGNvd3Bsb3QpCmxpYnJhcnkoc3ApCmBgYAoKI0ltcG9ydCBEYXRhCk5vdyBJIGltcG9ydCBteSBkYXRhLiBJIGZpbHRlciBmb3IgdGhlIEFycmFuIHBvc3Rjb2RlcywgKHNpbmNlIEFycmFuIGFsbCBiZWdpbnMgJ0tBMjcnKS4KYGBge3J9CiMjIEZpbmRpbmcgdGhlIEFycmFuIGNvb3JkaW5hdGVzCmxpYnJhcnkoZHBseXIpCmFsbGNvb3JkaW5hdGVzIDwtIHJlYWQuY3N2KCJhbGxkYXRhL3VrcG9zdGNvZGVzLmNzdiIpCmFycmFuY29vcmRpbmF0ZXMgPC0gZmlsdGVyKGFsbGNvb3JkaW5hdGVzLHN1YnN0cihwb3N0Y29kZSwxLDQpPT0iS0EyNyIpCmBgYAoKI1Bsb3QgQ29vcmRpbmF0ZXMKTm93IEkgcGxvdCB0aGVzZSBjb29yZGluYXRlcy4KYGBge3J9CiMjIFBsb3R0aW5nIHRoZSBBcnJhbiBjb29yZGluYXRlcwpnZ3Bsb3QoZGF0YSA9IGFycmFuY29vcmRpbmF0ZXMpICsKICBnZW9tX3BvaW50KG1hcHBpbmcgPSBhZXMoeCA9IGxvbmdpdHVkZSwgeSA9IGxhdGl0dWRlKSkgKwogIGdndGl0bGUoIkFycmFuIFBvc3Rjb2RlcyIpICsKICBsYWJzKHRpdGxlID0gIkFycmFuIFBvc3Rjb2RlcyIsIHggPSAiTG9uZ2l0dWRlIiwgeSA9ICJMYXRpdHVkZSIpICsKICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSkgKwogIHRoZW1lX2dyZXkoKSArCiAgY29vcmRfbWFwKCkKYGBgCgpOb3cgSSBjcmVhdGUgc29tZSBwbG90cy4KI0FycmFuIEJvcmRlcnMKYGBge3J9CnBjcyA8LSByZWFkX3NmKCJhbGxkYXRhL1Njb3RsYW5kX3Bjc18yMDExIikKCiNQcmludCBQb3N0IGNvZGVzIGxpc3RzCmFycmFuc3Vic2VjdCA8LSBmaWx0ZXIocGNzLHN1YnN0cihsYWJlbCwxLDQpPT0iS0EyNyIpCmFycmFuc3Vic2VjdCAlPiUKICBnZ3Bsb3QoKSArCiAgZ2VvbV9zZigpICsKICB0aGVtZShheGlzLnRleHQueD1lbGVtZW50X3RleHQoYW5nbGU9NDUsIGhqdXN0ID0gMSkpICsKICB0aGVtZV9ncmV5KCkKYGBgCgpBZnRlciBhIGxpdHRsZSBlZGl0aW5nIEkgY2FuIG92ZXJsYXkgdGhlIHR3by4KYGBge3J9CnNpbXBsZS5zZiA8LSBzdF9hc19zZihhcnJhbmNvb3JkaW5hdGVzLCBjb29yZHM9YygnbG9uZ2l0dWRlJywnbGF0aXR1ZGUnKSkKc3RfY3JzKHNpbXBsZS5zZikgPC0gNDMyNgpgYGAKCmBgYHtyfQpzaW1wbGUuc2YgJT4lIGdncGxvdCgpICsgZ2VvbV9zZigpICsKdGhlbWVfZ3JleSgpIApgYGAKCmBgYHtyfQphcnJhbnN1YnNlY3QgJT4lCiAgZ2dwbG90KCkgKwogIGdlb21fc2YoKSArCiAgdGhlbWUoYXhpcy50ZXh0Lng9ZWxlbWVudF90ZXh0KGFuZ2xlPTQ1LCBoanVzdCA9IDEpKSArCiAgdGhlbWVfZ3JleSgpICsKICBnZW9tX3NmKGRhdGE9c2ltcGxlLnNmKQpgYGAKCiNTaGFwZSBmaWxlcwpOb3cgSSBjYW4gbG9hZCB0aGUgU0lNRCBkYXRhLCBzdGFydGluZyB3aXRoIHRoZSBzaGFwZSBmaWxlcy4KYGBge3J9CiNJbXBvcnQgU0lNRCBkYXRhIGZyb20gaHR0cDovL3d3dy5nb3Yuc2NvdC9Ub3BpY3MvU3RhdGlzdGljcy9TSU1ECiNUaGUgIm5ldyBkYXRhIHpvbmUgYm91bmRhcmllcyB3aXRoIFNJTUQxNiByYW5rcyAoemlwcGVkIHNoYXBlZmlsZSkiCiMnMjAxMSBEYXRhIFpvbmUgYm91bmRhcmllcycKCkRaQm91bmRhcmllczIwMTYgPC0gcmVhZF9zZigiLi9hbGxkYXRhL1NHX1NJTURfMjAxNiIpCgojaHR0cHM6Ly9kYXRhLmdvdi51ay9kYXRhc2V0L3Njb3R0aXNoLWluZGV4LW9mLW11bHRpcGxlLWRlcHJpdmF0aW9uLXNpbWQtMjAxMgojaHR0cHM6Ly9kYXRhLmdvdi51ay9kYXRhc2V0L3Njb3R0aXNoLWluZGV4LW9mLW11bHRpcGxlLWRlcHJpdmF0aW9uLXNpbWQtMjAxMi9yZXNvdXJjZS9kNmZhODkyNC04M2RhLTRlODAtYTU2MC00ZWYwNDc3ZjIzMGIKRFpCb3VuZGFyaWVzMjAxMiA8LSByZWFkX3NmKCIuL2FsbGRhdGEvU0dfU0lNRF8yMDEyIikKRFpCb3VuZGFyaWVzMjAwOSA8LSByZWFkX3NmKCIuL2FsbGRhdGEvU0dfU0lNRF8yMDA5IikKRFpCb3VuZGFyaWVzMjAwNiA8LSByZWFkX3NmKCIuL2FsbGRhdGEvU0dfU0lNRF8yMDA2IikKRFpCb3VuZGFyaWVzMjAwNCA8LSByZWFkX3NmKCIuL2FsbGRhdGEvU0dfU0lNRF8yMDA0IikKYGBgCgojTG9hZCBTSU1EIGRhdGEKVGhlbiAoaGF2aW5nIGFscmVhZHkgZG93bmxvYWRlZCBpdCksIEkgY2FuIGxvYWQgdGhlIFNJTUQgZGF0YS4KYGBge3J9CiNMb29rIGF0IGRhdGEgZnJvbSAyMDE2ClNJTUQyMDE2IDwtcmVhZC5jc3YoIi4vYWxsZGF0YS8wMDUwNTI0NC5jc3YiKQpTSU1EMjAxNjIgPC1yZWFkX3NmKCIuL2FsbGRhdGEvU0dfU0lNRF8yMDE2IikKCiNMb29rIGF0IGRhdGEgZnJvbSAyMDEyClNJTUQyMDEyIDwtIHJlYWR4bDo6cmVhZF9leGNlbCgiLi9hbGxkYXRhL1NJTUQyMDEyLzAwNDEwNzcwLnhscyIpClNJTUQyMDEyMiA8LSByZWFkeGw6OnJlYWRfZXhjZWwoIi4vYWxsZGF0YS9TSU1EMjAxMi8wMDQxNjU1Mi54bHMiKQoKI0xvb2sgYXQgZGF0YSBmcm9tIDIwMDkKU0lNRDIwMDkgPC0gcmVhZHhsOjpyZWFkX2V4Y2VsKCIuL2FsbGRhdGEvU0lNRDIwMDkvMDA5NjU3OC54bHMiKQpTSU1EMjAwOTIgPC0gcmVhZHhsOjpyZWFkX2V4Y2VsKCIuL2FsbGRhdGEvU0lNRDIwMDkvMDA5NzgwNi54bHMiKQoKI0xvb2sgYXQgZGF0YSBmcm9tIDIwMDYKIyAyMDA5IGRhdGEgLSBTSU1EMjAwNiA8LSByZWFkeGw6OnJlYWRfZXhjZWwoIi4vYWxsZGF0YS9TSU1EMjAwNi8wMDk2NTc4LnhscyIpClNJTUQyMDA2MiA8LSByZWFkeGw6OnJlYWRfZXhjZWwoIi4vYWxsZGF0YS9TSU1EMjAwNi8wMDk3ODgwLnhscyIpCgojTG9vayBhdCBkYXRhIGZyb20gMjAwNApTSU1EMjAwNCA8LSByZWFkeGw6OnJlYWRfZXhjZWwoIi4vYWxsZGF0YS9TSU1EMjAwNC8wMDI3MDAzLnhscyIpCmBgYAoKI1NlbGVjdCBBcnJhbiBTSU1EIGRhdGEKSSBoYXZlIHRvIGNob29zZSB0aGUgcmlnaHQgY29sdW1ucyBtYW51YWxseSBpbiBvcmRlciB0byBzZWxlY3QgdGhlIEFycmFuIGRhdGEuCmBgYHtyfQojU2VsZWN0aW5nIEFycmFuRFoyMDE2CkFycmFuZHogPC0gYyg0NjcyLDQ2NjYsNDY2OSw0NjcxLDQ2NjcsNDY2OCw0NjcwKQoKI0hlYWx0aCBkb21haW4gcmFuawojMjAxNgphcnJhbjIwMTYgPC0gU0lNRDIwMTYyW0FycmFuZHosXQoKI0ZpbmQgcG9zdGNvZGUgbG9vay11cCwgS0EyNyBwb3N0Y29kZXMuIEZpbmQgdW5pcXVlIERaLiBGaW5kIHJvdyBwb3NpdGlvbnMuCgojU2VsZWN0aW5nIEFycmFuRFoyMDEyCkFycmFuZHoyMDEyIDwtIGMoNDQwOSw0MzcyLDQzNTMsNDM1Miw0MzUxLDQzNTAsNDM0OSkKCiMyMDEyCmFycmFuMjAxMiA8LSBEWkJvdW5kYXJpZXMyMDEyW0FycmFuZHoyMDEyLF0KIzIwMDkKYXJyYW4yMDA5IDwtIERaQm91bmRhcmllczIwMDlbQXJyYW5kejIwMTIsXQojMjAwNgphcnJhbjIwMDYgPC0gRFpCb3VuZGFyaWVzMjAwNltBcnJhbmR6MjAxMixdCiMyMDA0CmFycmFuMjAwNCA8LSBEWkJvdW5kYXJpZXMyMDA0W0FycmFuZHoyMDEyLF0KYGBgCgpUaGUgcmVhc29uIEkndmUgZG93bmxvYWRlZCBhbGwgdGhlIGRhdGF6b25lcyBzaGFwZWZpbGVzIGluZGl2aWR1YWxseSAodGhyZWUgc3RlcHMgdXApLCBpcyBiZWNhdXNlIHRoZXkgY2hhbmdlIGJldHdlZW4gMjAxNiBhbmQgMjAxMi4KCmBgYHtyfQphcnJhbjIwMTYyIDwtIGFycmFuMjAxNiAlPiUKICBzZWxlY3QoRGF0YVpvbmUsIGdlb21ldHJ5LCBQZXJjZW50aWxlKSAgJT4lCiAgbXV0YXRlKHllYXI9IjIwMTYiKQoKYXJyYW4yMDEyMiA8LSBhcnJhbjIwMTIgJT4lCiAgc2VsZWN0KERhdGFab25lLCBnZW9tZXRyeSwgUGVyY2VudGlsZSkgJT4lCiAgbXV0YXRlKHllYXI9IjIwMTIiKQoKYXJyYW4xNjEyIDwtIHJiaW5kKGFycmFuMjAxNjIsYXJyYW4yMDEyMikKYGBgCgpTZWUgdGhlIHNtYWxsIGRpZmZlcmVuY2UuCmBgYHtyfQphcnJhbjE2MTIgJT4lCiAgZ2dwbG90KCkgKwogIGdlb21fc2YoYWVzKGZpbGwgPSBEYXRhWm9uZSkpICsKICBmYWNldF93cmFwKCd5ZWFyJykgKwogIHRoZW1lX2dyZXkoKSArCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikgKwogIHRoZW1lKGF4aXMudGV4dC54PWVsZW1lbnRfdGV4dChhbmdsZT00NSwgaGp1c3QgPSAxKSkKYGBgCgpOb3cgSSB3YW50IHRvIHBsb3QgYWxsIHRoZSBkYXRhLCBmaXJzdCBJIGNvbWJpbmUgaXQgYWxsIGludG8gb25lIHRhYmxlLgpGaXJzdCBJIHN1YnNlbGVjdCB0aGUgZGF0YSBJIHdhbnQgZnJvbSB0aGUgYXBwcm9wcmlhdGUgY29sdW1ucy4KYGBge3J9CmFycmFuMjAwOTIgPC0gYXJyYW4yMDA5ICU+JQogIHNlbGVjdChEYXRhWm9uZSwgZ2VvbWV0cnksIFBlcmNlbnRpbGUpICU+JQogIG11dGF0ZSh5ZWFyPSIyMDA5IikKCmFycmFuMjAwNjIgPC0gYXJyYW4yMDA2ICU+JQogIHNlbGVjdChEYXRhWm9uZSwgZ2VvbWV0cnksIFBlcmNlbnRpbGUpICU+JQogIG11dGF0ZSh5ZWFyPSIyMDA2IikKCmFycmFuMjAwNDIgPC0gYXJyYW4yMDA0ICU+JQogIHNlbGVjdChEYXRhWm9uZSwgZ2VvbWV0cnksIFBlcmNlbnRpbGUpICU+JQogIG11dGF0ZSh5ZWFyPSIyMDA0IikKCmFycmFuc2ltZCA8LSByYmluZChhcnJhbjIwMTYyLGFycmFuMjAxMjIsYXJyYW4yMDA5MixhcnJhbjIwMDYyLGFycmFuMjAwNDIpCmBgYAoKI0FycmFuIFBlcmNlbnRpbGUgUGxvdHMKTm93IEkgcGxvdCB0aGUgcGVyY2VudGlsZXMuCmBgYHtyfQphcnJhbnNpbWQgJT4lCiAgZ2dwbG90KCkgKwogIGdlb21fc2YoYWVzKGZpbGwgPSBQZXJjZW50aWxlKSkgKwogIGZhY2V0X3dyYXAoJ3llYXInKSArCiAgdGhlbWVfZ3JleSgpICsKICB0aGVtZShheGlzLnRleHQueD1lbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50aWNrcy54PWVsZW1lbnRfYmxhbmsoKSwgYXhpcy50ZXh0Lnk9ZWxlbWVudF9ibGFuaygpLAogICAgICAgIGF4aXMudGlja3MueT1lbGVtZW50X2JsYW5rKCkpCmBgYAoKVGhlcmUgd2UgYXJlLiBOb3QgdGhlIFNJTUQgaGVhbHRoIHBlcmNlbnRpbGVzIG9mIEFycmFuIHpvbmVzIHRocm91Z2hvdXQgU0lNRCBoaXN0b3J5LiBBbmQgSSd2ZSBsZWFybmVkIGEgbGl0dGxlIGJpdCBhYm91dCBncmFwaGljcyBpbiBSLgoKSWYgSSB3YW50ZWQgdG8gSSBjb3VsZCBzaG93IHRoZSB6b25lcyBpbmRpdmlkdWFsbHkuLgoKRmlyc3QgSSBmaW5kIHRoZSB1bmlxdWUgem9uZXMuIChUaGVyZSBhcmUgMTQuIDcgWm9uZXMgMjAxNiwgNyBab25lcyBwcmUtMjAxNikKCmBgYHtyfQpkYXRhem9uZXMgPC0gdW5pcXVlKGFycmFuc2ltZCREYXRhWm9uZSkKYGBgCgpJJ2xsIGhhdmUgdG8gZmluZCBvdXQgYSBzaW1wbGVyIHdheSB0byBkbyB0aGlzIGJ1dC4uCgojUHJlLTIwMTYgSW5kaXZpZHVhbCBab25lcwpgYGB7cn0KUzAxMDA0NDA5IDwtIGZpbHRlcihhcnJhbnNpbWQsIERhdGFab25lPT0iUzAxMDA0NDA5IikKUzAxMDA0MzcyIDwtIGZpbHRlcihhcnJhbnNpbWQsIERhdGFab25lPT0iUzAxMDA0MzcyIikKUzAxMDA0MzUzIDwtIGZpbHRlcihhcnJhbnNpbWQsIERhdGFab25lPT0iUzAxMDA0MzUzIikKUzAxMDA0MzUyIDwtIGZpbHRlcihhcnJhbnNpbWQsIERhdGFab25lPT0iUzAxMDA0MzUyIikKUzAxMDA0MzUxIDwtIGZpbHRlcihhcnJhbnNpbWQsIERhdGFab25lPT0iUzAxMDA0MzUxIikKUzAxMDA0MzUwIDwtIGZpbHRlcihhcnJhbnNpbWQsIERhdGFab25lPT0iUzAxMDA0MzUwIikKUzAxMDA0MzQ5IDwtIGZpbHRlcihhcnJhbnNpbWQsIERhdGFab25lPT0iUzAxMDA0MzQ5IikKYGBgCgpgYGB7cn0KcHJlMjAxNmxpc3QgPC0gbGlzdChTMDEwMDQ0MDksIFMwMTAwNDM3MiwgUzAxMDA0MzUzLCBTMDEwMDQzNTIsIFMwMTAwNDM1MSwgUzAxMDA0MzUwLCBTMDEwMDQzNDkpCmBgYAoKYGBge3J9CmZ1bmN0aW9uMSA8LSBmdW5jdGlvbihhcmd1bWVudCkgCnsKICBhcmd1bWVudCAlPiUKICBnZ3Bsb3QoKSArCiAgZ2VvbV9zZihhZXMoZmlsbCA9IFBlcmNlbnRpbGUpKSArCiAgZmFjZXRfd3JhcCgneWVhcicpICsKICB0aGVtZV9ncmV5KCkgKwogIHRoZW1lKGF4aXMudGV4dC54PWVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRpY2tzLng9ZWxlbWVudF9ibGFuaygpKQp9CmBgYAoKYGBge3J9CmZ1bmN0aW9uMiA8LSBmdW5jdGlvbihhcmd1bWVudCkgCnsKICBhcnJhbnN1YnNlY3QgJT4lCiAgZ2dwbG90KCkgKwogIGdlb21fc2YoKSArCiAgdGhlbWVfZ3JleSgpICsKICB0aGVtZShheGlzLnRleHQueD1lbGVtZW50X3RleHQoYW5nbGU9NDUsIGhqdXN0ID0gMSkpICsKICBnZW9tX3NmKGRhdGE9IGFyZ3VtZW50LCBhZXMoZmlsbCA9IERhdGFab25lKSkKfQpgYGAKCmBgYHtyfQpmdW5jdGlvbjMgPC0gZnVuY3Rpb24oYXJndW1lbnQpIAp7CiAgYXJndW1lbnQgJT4lCiAgZ2dwbG90KCkgKwogIGdlb21fc2YoZGF0YSA9IGFycmFuc3Vic2VjdCkgKwogIGdlb21fc2YoYWVzKGZpbGwgPSBQZXJjZW50aWxlKSkgKwogIGZhY2V0X3dyYXAoJ3llYXInKSArCiAgdGhlbWVfZ3JleSgpICsKICB0aGVtZShheGlzLnRleHQueD1lbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50aWNrcy54PWVsZW1lbnRfYmxhbmsoKSkKfQpgYGAKCmBgYHtyfQpmdW5jdGlvbjQgPC0gZnVuY3Rpb24oYXJndW1lbnQpIAp7CiAgcGxvdF9ncmlkKChmdW5jdGlvbjEoYXJndW1lbnQpKSwgKGZ1bmN0aW9uMihhcmd1bWVudCkpLCBsYWJlbHMgPSBjKCJBIiwgIkIiKSkKfQpgYGAKCmBgYHtyfQpsYXBwbHkocHJlMjAxNmxpc3QsIGZ1bmN0aW9uNCkKYGBgCgojMjAxNgpOb3cgSSBhcHBseSB0aGUgc2FtZSBmdW5jdGlvbnMgdG8gdGhlIHBvc3QtMjAxNiBab25lcwpgYGB7cn0KYXJyYW5zdWJzZWN0IDwtIGZpbHRlcihwY3Msc3Vic3RyKGxhYmVsLDEsNCk9PSJLQTI3IikKClMwMTAxMTE3NyA8LSBmaWx0ZXIoYXJyYW5zaW1kLCBEYXRhWm9uZT09IlMwMTAxMTE3NyIpClMwMTAxMTE3MSA8LSBmaWx0ZXIoYXJyYW5zaW1kLCBEYXRhWm9uZT09IlMwMTAxMTE3MSIpClMwMTAxMTE3NCA8LSBmaWx0ZXIoYXJyYW5zaW1kLCBEYXRhWm9uZT09IlMwMTAxMTE3NCIpClMwMTAxMTE3NiA8LSBmaWx0ZXIoYXJyYW5zaW1kLCBEYXRhWm9uZT09IlMwMTAxMTE3NiIpClMwMTAxMTE3MiA8LSBmaWx0ZXIoYXJyYW5zaW1kLCBEYXRhWm9uZT09IlMwMTAxMTE3MiIpClMwMTAxMTE3MyA8LSBmaWx0ZXIoYXJyYW5zaW1kLCBEYXRhWm9uZT09IlMwMTAxMTE3MyIpClMwMTAxMTE3NSA8LSBmaWx0ZXIoYXJyYW5zaW1kLCBEYXRhWm9uZT09IlMwMTAxMTE3NSIpCmBgYAoKYGBge3J9CnBvc3QyMDE2bGlzdCA8LSBsaXN0KFMwMTAxMTE3NywgUzAxMDExMTcxLCBTMDEwMTExNzQsIFMwMTAxMTE3NiwgUzAxMDExMTcyLCBTMDEwMTExNzMsIFMwMTAxMTE3NSkKYGBgCgpgYGB7cn0KbGFwcGx5KHByZTIwMTZsaXN0LCBmdW5jdGlvbjQpCmBgYAoKI1Bsb3QgdGhlIHBlcmNlbnRpbGVzIGFzIGJhciBjaGFydHMuCgpQcmUtMjAxNgpgYGB7cn0KYXJyYW5zaW1kMiA8LSBkcGx5cjo6ZmlsdGVyKGFycmFuc2ltZCwgeWVhciA8IDIwMTYpCgphcnJhbnNpbWQyICU+JQpnZ3Bsb3QoYWVzKHg9eWVhciwgeT1QZXJjZW50aWxlKSkgKwogIGdlb21fYmFyKHN0YXQ9ImlkZW50aXR5IikgKwogIGZhY2V0X3dyYXAoJ0RhdGFab25lJykgKwogIHRoZW1lX2dyZXkoKSArCiAgbGFicyh0aXRsZSA9ICJBcnJhbiBTSU1EIERhdGF6b25lcyIsIHggPSAiWWVhciIsIHkgPSAiUGVyY2VudGlsZSIpICsKICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSkKYGBgCgpQb3N0LTIwMTYKYGBge3J9CmFycmFuc2ltZDMgPC0gZHBseXI6OmZpbHRlcihhcnJhbnNpbWQsIHllYXIgPj0gMjAxNikKCmFycmFuc2ltZDMgJT4lCmdncGxvdChhZXMoeD15ZWFyLCB5PVBlcmNlbnRpbGUpKSArCiAgZ2VvbV9iYXIoc3RhdD0iaWRlbnRpdHkiKSArCiAgZmFjZXRfd3JhcCgnRGF0YVpvbmUnKSArCiAgdGhlbWVfZ3JleSgpICsKICBsYWJzKHRpdGxlID0gIkFycmFuIFNJTUQgRGF0YXpvbmVzIiwgeCA9ICJZZWFyIiwgeSA9ICJQZXJjZW50aWxlIikgKwogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUpKQpgYGAKCk5vdyBJIHdhbnQgdG8gb3ZlcmxheSB0aGUgcG9zdGNvZGVzIGZvciBhIHBhcnRpY3VsYXIgc2hhcGVmaWxlLCBpbiB0aGlzIGNhc2UgYnkgRGF0YXpvbmUuClRvIGRvIHRoaXMgSSd2ZSBjb252ZXJ0ZWQgYm90aCB0aGUgQXJyYW4gY29vcmRpbmF0ZXMgYW5kIEFycmFuICgyMDE2KSBzaGFwZWZpbGVzIGludG8gU3BhdGlhbCBQb2ludHMvUG9seWdvbnMsIGNvbnZlcnRlZCB0aGVtIGludG8gYSBjb21tb24gQ1JTLCBhbmQgdGhlbiBjb21wYXJlZCB0aGVtIGJ5IHVzaW5nIG92ZXIoKS4KYGBge3J9CmV4YW1wbGVzaGFwZXMgPC0gc2Y6Ojphc19TcGF0aWFsKGFycmFuMjAxNiRnZW9tKQpleGFtcGxlcG9pbnRzIDwtIHNmOjo6YXNfU3BhdGlhbChzaW1wbGUuc2YkZ2VvbSkKCmV4YW1wbGVwb2ludHMgPC0gc3BUcmFuc2Zvcm0oZXhhbXBsZXBvaW50cywgQ1JTKCIrcHJvaj1sb25nbGF0ICtkYXR1bT1XR1M4NCIpKQpleGFtcGxlc2hhcGVzIDwtIHNwVHJhbnNmb3JtKGV4YW1wbGVzaGFwZXMsIENSUygiK3Byb2o9bG9uZ2xhdCArZGF0dW09V0dTODQiKSkKCm5hbWluZ2R6cG9zdGNvZGUgPC0gb3ZlcihleGFtcGxlc2hhcGVzLCBleGFtcGxlcG9pbnRzLCByZXR1cm5MaXN0ID0gVFJVRSkKYGBgCgpJIGNhbiB0aGVuIHRha2UgYSBtZW1iZXIgcmVmZXJlbmNlIGZyb20gdGhlIG9yZ2luYWwgcG9zdGNvZGUgbGlzdCwgd2hpY2ggZ2l2ZXMgbWUgYSBzZWxlY3Rpb24gb2YgdGhlIHJvd3MgaW4gdGhhdCBEWi4gRm9yIHNpbXBsaWNpdHkgSSd2ZSB3cml0dGVuIHRoaXMgYXMgYSBuZXcgZnVuY3Rpb24uIAoKVW5mb3J0dW5hdGVseSwgSSBoYXZlbid0IHdvcmtlZCBvdXQgaG93IHRvIGNvb3JkaW5hdGUgdGhlIG5ldyBJRCB3aXRoIHRoZSBvcmlnaW5hbCBEWiBuYW1lcyB5ZXQsIHNvIEkgaGF2ZSB0byBzZWxlY3QgYnkgdXNpbmcgdGhlIGFwcHJvcHJpYXRlIElEIGZvciBlYWNoIERaLgojRnVuY3Rpb24gc2VsZWN0aW5nIHNpbXBsZS5zZiBieSBEWiBJRC4KYGBge3J9CmZ1bmN0aW9uNiA8LSBmdW5jdGlvbihhcmd1bWVudCkgCnsKICBzaW1wbGUuc2ZbbmFtaW5nZHpwb3N0Y29kZVtbYXJndW1lbnRdXSxdCn0KYGBgCgpJIGNhbiB0aGVuIHVzZSB0aGUgYWJvdmUsIGFuZCBwbG90IG92ZXIgdGhlIGFwcHJvcHJpYXRlIERaIHNoYXBlZmlsZS4KZS5nCgojUHJvamVjdGluZyB0aGUgY29vcmRpbmF0ZSBzZWxlY3Rpb25zCmBgYHtyfQpmdW5jdGlvbjEoUzAxMDA0MzcyKSArCiAgZ2VvbV9zZihkYXRhPWZ1bmN0aW9uNigyKSkKZnVuY3Rpb24yKFMwMTAwNDM3MikgKwogIGdlb21fc2YoZGF0YT1mdW5jdGlvbjYoMikpCmZ1bmN0aW9uMyhTMDEwMDQzNzIpICsKICBnZW9tX3NmKGRhdGE9ZnVuY3Rpb242KDIpKQpgYGAKCklmIEkgZWRpdCBmdW5jdGlvbiA0IGEgbGl0dGxlIHNvIHRoYXQgdGhlIGdlb21fc2YgbGF5ZXIgaXMgYSBzZWNvbmQgYXJndW1lbnQgdGhlbiBJIGNhbiBhbHNvIHVzZSBmdW5jdGlvbiA0LgoKYGBge3J9CmZ1bmN0aW9uNC41IDwtIGZ1bmN0aW9uKGFyZ3VtZW50LCBhcmd1bWVudDIpIAp7CiAgYSA8LSBmdW5jdGlvbjEoYXJndW1lbnQpCiAgYiA8LSBmdW5jdGlvbjIoYXJndW1lbnQpICsKICBnZW9tX3NmKGRhdGE9ZnVuY3Rpb242KGFyZ3VtZW50MikpCgogIHBsb3RfZ3JpZChhLCBiLCBsYWJlbHMgPSBjKCJBIiwgIkIiKSkKfQpgYGAKCmBgYHtyfQpmdW5jdGlvbjQuNShTMDEwMDQzNzIsMikKYGBgCgpJJ3ZlIGFsc28gbWFkZSBhbm90aGVyIGZ1bmN0aW9uIHRvIHBsb3QgdGhlIERaIG9uIGl0J3Mgb3duIHdpdGggY29vcmRpbmF0ZXMuCmBgYHtyfQpmdW5jdGlvbjUgPC0gZnVuY3Rpb24oYXJndW1lbnQsIGFyZ3VtZW50MikgCnsKICBhcmd1bWVudCAlPiUKICBnZ3Bsb3QoKSArCiAgZ2VvbV9zZigpICsKICB0aGVtZV9ncmV5KCkgKwogIGdlb21fc2YoZGF0YT1mdW5jdGlvbjYoYXJndW1lbnQyKSkgKwogIHRoZW1lKGF4aXMudGV4dC54PWVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRpY2tzLng9ZWxlbWVudF9ibGFuaygpKQp9CmBgYAoKYGBge3J9CmZ1bmN0aW9uNShTMDEwMDQzNzIsMikKYGBgCgoK